package com.linln.admin.app.service.task;

import com.linln.admin.app.constants.AppConstants;
import com.linln.admin.app.constants.TaskTypeEnum;
import com.linln.admin.app.domain.AppInfo;
import com.linln.admin.app.domain.AppVersion;
import com.linln.admin.app.domain.RepoAccount;
import com.linln.admin.app.domain.VersionApp;
import com.linln.admin.app.service.branch.BranchHelper;
import com.linln.admin.system.domain.TaskQueue;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 创建开发分支
 */
@Service
@Slf4j
public class CreateReleaseBranchTask extends AbstractTaskExecutor {
    /**
     * 是否可以处理这个任务
     *
     * @param t
     * @return
     */
    @Override
    public boolean support(TaskQueue t) {
        return t != null && TaskTypeEnum.CREATE_RELEASE_BRANCH.getType().equals(t.getType());
    }

    /**
     * 处理任务，并返回处理结果
     *
     * @param t
     * @return true-成功; 其它-false
     */
    @Override
    public boolean exec(TaskQueue t) {
        Long versionId = t.getRelate_id();
        Optional<AppVersion> ver = versionRepository.findById(versionId);
        if (!ver.isPresent()) {
            throw new IllegalArgumentException("对应的版本信息不存在！");
        }
        AppVersion version = ver.get();
        if (AppConstants.YES.equals(version.getHotfix_flag())) {
            return false;//紧急修复版本不需要切release分支
        }
        List<VersionApp> vas = versionAppRepository.findByVersionId(versionId);
        if (vas == null || vas.isEmpty()) {
            return true;
        }

        String baseVer = version.getVersion().trim().replace(" ", "");
        if (baseVer.startsWith(AppConstants.BRANCH_DEV_PREFIX)) {
            baseVer = baseVer.substring(4);
        }

        for (VersionApp va : vas) {
            if (va == null || va.getApp_id() == null) {
                continue;
            }
            if (AppConstants.YES.equals(va.getHas_release())) {
                continue;//如果已经有release分支，则不处理
            }
            Optional<AppInfo> app = infoRepository.findById(va.getApp_id());
            if (!app.isPresent()) {
                versionAppRepository.delete(va);
                continue;
            }
            String release = AppConstants.BRANCH_RELEASE_PREFIX + baseVer;
            String dev = AppConstants.BRANCH_DEV_PREFIX + baseVer;
            AppInfo info = app.get();
            RepoAccount account = getRepoAccount(info.getRepo_account_id());
            try {//创建release分支
                if (BranchHelper.findHandler(info.getRepo_type()).createNewBranch(baseVer, info.getRepo_url(), account.getAccount(), account.getPass(), info.getBase(), release)) {
                    va.setHas_release(AppConstants.YES);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

            try {//将prod合并到dev
                va.setMerge_from_time(new Date());
                if (BranchHelper.findHandler(info.getRepo_type()).mergeBranch(baseVer, info.getRepo_url(), account.getAccount(), account.getPass(), info.getBase(), dev)) {
                    va.setMerge_from_status(AppConstants.VERSION_MERGE_STATUS_AUTO_MERGED);
                } else {
                    va.setMerge_from_status(AppConstants.VERSION_MERGE_STATUS_CONFLICT);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

            try {//将dev合并到release
                va.setMerge_to_time(new Date());
                if (BranchHelper.findHandler(info.getRepo_type()).mergeBranch(baseVer, info.getRepo_url(), account.getAccount(), account.getPass(), dev, release)) {
                    va.setMerge_to_status(AppConstants.VERSION_MERGE_STATUS_AUTO_MERGED);
                } else {
                    va.setMerge_to_status(AppConstants.VERSION_MERGE_STATUS_CONFLICT);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            versionAppRepository.save(va);
        }
        return true;
    }
}
